<template>
  <div id="home">
    <div id="leftSide">
      <div id="top">
        <div>
          <el-button type="primary" id="start" @click="handleStartClick"
            >{{ isPaused ? "暂停" : "继续" }}
          </el-button>
        </div>
        <div>
          <p id="pause" v-if="bottomClick">
            {{ "当前演示服务   " + mode }}
          </p>
        </div>
      </div>
      <div id="bottom">
        <div>
          <el-button type="success" id="icmp" @click="handleIcmpClick"
            >ICMP
          </el-button>
        </div>
        <div>
          <el-button type="success" id="udp" @click="handleUdpClick"
            >UDP
          </el-button>
        </div>
        <div>
          <el-button type="success" id="arp" @click="handleArpClick"
            >ARP
          </el-button>
        </div>
      </div>
    </div>
    <div id="rightSide">
      <div style="display: flex; flex-direction: column; align-items: center">
        <l4
          :recv="this.layerHistoryContent[0]"
          :send="this.layerHistoryContent[1]"
        />
        <div>
          <arrow
            :description="this.arrowHistoryContent[0]"
            :rotation="90"
            color="blue"
          />
          <arrow
            :description="this.arrowHistoryContent[9]"
            :rotation="270"
            color="black"
          />
        </div>
        <l3
          :recv="this.layerHistoryContent[2]"
          :send="this.layerHistoryContent[3]"
        />
        <div>
          <arrow
            :description="this.arrowHistoryContent[1]"
            :rotation="90"
            color="red"
          />
          <arrow
            :description="this.arrowHistoryContent[8]"
            :rotation="270"
            color="grey"
          />
        </div>
        <l2
          :recv="this.layerHistoryContent[4]"
          :send="this.layerHistoryContent[5]"
        />
      </div>

      <div
        style="
          height: 750px;
          display: flex;
          flex-direction: column;
          justify-content: end;
        "
      >
        <arrow
          :description="this.arrowHistoryContent[7]"
          :rotation="180"
          color="blue"
        />
        <arrow
          :description="this.arrowHistoryContent[2]"
          :rotation="0"
          color="black"
        />
      </div>

      <div style="display: flex; flex-direction: column; align-items: center">
        <l4
          :recv="this.layerHistoryContent[10]"
          :send="this.layerHistoryContent[11]"
        />
        <div>
          <arrow
            :description="this.arrowHistoryContent[5]"
            :rotation="90"
            color="blue"
          />
          <arrow
            :description="this.arrowHistoryContent[4]"
            :rotation="270"
            color="black"
          />
        </div>
        <l3
          :recv="this.layerHistoryContent[8]"
          :send="this.layerHistoryContent[9]"
        />
        <div>
          <arrow
            :description="this.arrowHistoryContent[6]"
            :rotation="90"
            color="red"
          />
          <arrow
            :description="this.arrowHistoryContent[3]"
            :rotation="270"
            color="grey"
          />
        </div>
        <l2
          :recv="this.layerHistoryContent[6]"
          :send="this.layerHistoryContent[7]"
        />
      </div>
    </div>
  </div>
</template>

<script>
import Arrow from "@/components/Arrow/index.vue";
import NetworkApi from "@/api/route";
import { L2, L3, L4 } from "@/components/Layer";

export default {
  name: "Home",
  components: {
    L2,
    L3,
    L4,
    Arrow,
  },
  watch: {
    index: function (val, oldVal) {
      if (val === oldVal) return;
      switch (this.mode) {
        case "ARP":
          this.getL2Packet();
          break;
        default:
          this.getL2Packet();
          this.getL3Packet();
          break;
      }
      this.getRowPacket();
    },
  },
  data() {
    return {
      isPaused: true,
      bottomClick: false,
      currentInterval: "",
      index: 0,
      // ICMP/UDP/ARP
      mode: "ICMP",
      transHistory: [],
      // 从左上到右上再回到左下的顺序
      arrowHistory: new Array(10).fill({
        header: "{}",
        content: "{}",
      }),
      // 从左上到右上的顺序,左上第四层为 0 1
      layerHistory: new Array(12).fill({
        header: "{}",
        content: "{}",
      }),
    };
  },
  computed: {
    arrowHistoryContent() {
      return this.arrowHistory.map((i) => i.content || "");
    },
    layerHistoryContent() {
      return this.layerHistory.map((i) => i.content || "");
    },
  },
  methods: {
    async init() {
      this.index = 0;
      this.transHistory = [];
      this.arrowHistory = new Array(10).fill({
        header: "{}",
        content: "{}",
      });
      this.layerHistory = new Array(12).fill({
        header: "{}",
        content: "{}",
      });
      try {
        const data = await NetworkApi[this.mode](this.index).data;
        if (!data) {
          throw new Error("返回数据为空");
        }
        this.transHistory = [data];
        this.index++;
      } catch (e) {
        console.log("网络错误：", e);
      }
    },
    handleUdpClick() {
      clearInterval(this.currentInterval);
      this.mode = "UDP";
      NetworkApi["Submit"](this.mode.toLowerCase());
      console.log(this.arrowHistory);
      this.init();
      this.bottomClick = true;
      this.changeInterval();
    },
    handleIcmpClick() {
      clearInterval(this.currentInterval);
      this.mode = "ICMP";
      NetworkApi["Submit"](this.mode.toLowerCase());
      this.init();
      this.bottomClick = true;
      this.changeInterval();
    },
    handleArpClick() {
      clearInterval(this.currentInterval);
      this.mode = "ARP";
      NetworkApi["Submit"](this.mode.toLowerCase());
      this.init();
      this.bottomClick = true;
      this.changeInterval();
    },
    handleStartClick() {
      // 暂停的情况下点击，那就是继续
      if (!this.isPaused) {
        this.isPaused = !this.isPaused;
        this.changeInterval();
      } else {
        // 继续的情况下点击 那么就清除定时器，停止发消息
        clearInterval(this.currentInterval);
        this.isPaused = !this.isPaused;
      }
    },
    changeInterval() {
      this.currentInterval = setInterval(
        () =>
          NetworkApi[this.mode](this.index).then((res) => {
            console.log(res);
            console.log(typeof res);
            this.transHistory.push(res.data);
            this.index++;
          }),
        1100
      );
    },
    getL3Packet() {
      const lastPacket = this.transHistory[this.transHistory.length - 1];
      if (lastPacket.header === "ICMP recv") {
        this.layerHistory.splice(8, 1, { ...lastPacket });
      } else if (lastPacket.header === "ICMP send") {
        this.layerHistory.splice(9, 1, { ...lastPacket });
      }
    },
    getL2Packet() {
      const lastPacket = this.transHistory[this.transHistory.length - 1];
      if (
        lastPacket.header === "ARP lookup invoked" ||
        lastPacket.header === "Received ARP"
      ) {
        this.layerHistory.splice(6, 1, { ...lastPacket });
      } else if (
        lastPacket.header.includes("ARP cache hit") ||
        lastPacket.header === "Send ARP request" ||
        lastPacket.header === "Send ARP response"
      ) {
        this.layerHistory.splice(7, 1, { ...lastPacket });
      }
    },
    getRowPacket() {
      const lastPacket = this.transHistory[this.transHistory.length - 1];
      switch (lastPacket.header) {
        case "L2 recv":
          this.arrowHistory.splice(2, 1, { ...lastPacket });
          break;
        case "L3 recv":
          this.arrowHistory.splice(3, 1, { ...lastPacket });
          break;
        case "L4 recv":
          this.arrowHistory.splice(4, 1, { ...lastPacket });
          break;
        case "L4 send":
          this.arrowHistory.splice(5, 1, { ...lastPacket });
          break;
        case "L3 send":
          this.arrowHistory.splice(6, 1, { ...lastPacket });
          break;
        case "L2 send":
          this.arrowHistory.splice(7, 1, { ...lastPacket });
      }
    },
  },
};
</script>

<style scoped lang="less">
#home {
  display: flex;
  height: 90vh;

  #leftSide {
    background: #42b983;
    width: 100px;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    align-items: center;

    #top {
      height: 50%;
      display: flex;
      flex-direction: column;
      justify-content: start;

      #start {
        margin-top: 10px;
      }

      #pause {
        margin-top: 20px;
        writing-mode: tb-rl;
        font-size: large;
      }
    }

    #bottom {
      height: 50%;
      display: flex;
      flex-direction: column;
      justify-content: end;

      #icmp {
        margin-bottom: 10px;
      }

      #udp {
        margin-bottom: 10px;
      }

      #arp {
        margin-bottom: 10px;
      }
    }
  }

  #rightSide {
    display: flex;
    margin-left: 100px;
  }
}
</style>
